package com.mikufufu.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mikufufu.blog.mapper.RoleMapper;
import com.mikufufu.blog.common.entity.SysUser;
import com.mikufufu.blog.model.entity.RoleNav;
import com.mikufufu.blog.security.enums.RoleCode;
import com.mikufufu.blog.model.vo.admin.NavVO;
import com.mikufufu.blog.security.utils.AuthUtils;
import com.mikufufu.blog.service.RoleNavService;
import com.mikufufu.blog.utils.BeanUtil;
import com.mikufufu.blog.utils.StringUtils;
import com.mikufufu.blog.mapper.NavMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mikufufu.blog.model.entity.Nav;
import com.mikufufu.blog.service.NavService;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 导航信息表 服务实现类
 * 
 */
@Service
public class NavServiceImpl extends ServiceImpl<NavMapper, Nav> implements NavService{

    /**
     * 顶级父导航id
     */
    private static final int TOP_PARENT_ID = 0;

    @Autowired
    private RoleNavService roleNavService;

    @Autowired
    private RoleMapper roleMapper;

    @Override
    public List<NavVO> getNavTree() {
        Integer roleId;
        SysUser user = AuthUtils.getUser();
        if (StringUtils.isNotEmpty(user) && user.getRole().contains("admin")) {
            roleId = user.getRoleId();
        }else {
            roleId = roleMapper.getRoleIdByCode(RoleCode.ROLE_VISITOR.getCode());
        }
        List<Nav> list = baseMapper.getNavListByRole(roleId);
        if (StringUtils.isNotEmpty(list)) {
            List<NavVO> navVOList = list.stream().map(nav -> BeanUtil.copy(nav, NavVO.class)).collect(Collectors.toList());
            // 如果列表非空，尝试构建导航树
            //return getTree(navVOList,TOP_PARENT_ID);
            return getTreeNavUseMap(navVOList);
        }
        // 若为空则直接返回空列表
        return Collections.emptyList();
    }

    @Override
    public List<NavVO> listByParentId(Integer parentId) {
        List<Nav> list = baseMapper.listByParentId(parentId);
        return list.stream().map(nav -> BeanUtil.copy(nav, NavVO.class)).collect(Collectors.toList());
    }

    @Override
    public List<NavVO> listByParentIdAndStatus(Integer parentId, Integer status) {
        List<Nav> list = baseMapper.listByParentIdAndStatus(parentId,status);
        return list.stream().map(nav -> BeanUtil.copy(nav, NavVO.class)).collect(Collectors.toList());
    }

    @Override
    public Boolean addRoleNav(Integer roleId, Integer navId) {
        RoleNav roleNav = new RoleNav();
        roleNav.setRoleId(roleId);
        roleNav.setNavId(navId);
        Nav nav = this.getById(navId);
        if(StringUtils.isEmpty(nav)){
            throw new RuntimeException("导航不存在");
        }
        return roleNavService.save(roleNav);
    }

    @Override
    public List<NavVO> getTreeByRoleId(Integer roleId) {
        return baseMapper.getTreeByRoleId(roleId);
    }

    @Override
    public List<NavVO> getNavList(String navName, Integer status) {
        List<Nav> list = this.list(new LambdaQueryWrapper<Nav>()
                .like(StringUtils.isNotEmpty(navName), Nav::getNavName, navName)
                .eq(StringUtils.isNotEmpty(status), Nav::getStatus, status)
        );
        if (StringUtils.isNotEmpty(list)) {
            List<NavVO> navVOList = list.stream().map(nav -> BeanUtil.copy(nav, NavVO.class)).collect(Collectors.toList());
            // 如果列表非空，尝试构建导航树
            return getAllNoParentTree(navVOList);
        }
        // 若为空则直接返回空列表
        return Collections.emptyList();
    }

    @Override
    public NavVO getNavVO(Integer navId) {
        List<Nav> list = this.list(new LambdaQueryWrapper<Nav>().eq(Nav::getParentId, navId));
        if (StringUtils.isNotEmpty(list)) {
            List<NavVO> subNavList = list.stream().map(nav -> BeanUtil.copy(nav, NavVO.class)).collect(Collectors.toList());
            return this.getTreeByParentId(subNavList, navId).get(0);
        }
        return null;
    }

    /**
     * 获取导航信息表树形数据
     * 从导航信息表列表中，根据指定的父导航ID，构建一个树形结构的导航数据列表。
     * @param list 导航信息表列表，不可为null且不可为空。
     * @param parentId 父导航id，用于筛选父级导航项。
     * @return 返回一个导航信息表的树形结构列表，其中每个导航项可能包含子导航项。
     */
    public List<NavVO> getTree(List<NavVO> list, Integer parentId) {
        // 检查输入列表是否为空，若为空则直接返回空列表
        if (StringUtils.isEmpty(list)) {
            return Collections.emptyList();
        }
        // 使用流处理数据，过滤出父ID匹配的导航项，并转换为NavVO对象
        return list.stream().filter(nav -> nav.getParentId().equals(parentId)).peek(nav -> nav.setSubNavList(getTree(list,nav.getId()).stream().peek(subNav -> subNav.setPath(nav.getPath() + "/" + subNav.getPath())).collect(Collectors.toList()))).collect(Collectors.toList());
    }

    /**
     * 根据导航列表和父级ID，构建导航的树形结构。
     * @param list 导航实体列表，不应为null或空。
     * @return 返回构建好的导航树形结构列表。每个导航节点包含其子导航节点列表。
     */
    private List<NavVO> getTreeNavUseMap(List<NavVO> list) {
        // 检查输入列表是否为空，若为空则直接返回空列表
        if (StringUtils.isEmpty(list)) {
            return Collections.emptyList();
        }

        // 遍历列表，将每个Nav实体复制到NavVO中，并存入映射表
        Map<Integer, List<NavVO>> map = list.stream().collect(Collectors.groupingBy(Nav::getParentId));

        list.forEach(navVO -> {
            List<NavVO> subNavList = map.get(navVO.getId());
            if (StringUtils.isNotEmpty(subNavList)) {
                navVO.setSubNavList(subNavList.stream().peek(subNav -> subNav.setPath(navVO.getPath() + "/" + subNav.getPath())).collect(Collectors.toList()));
            }
        });

        return list.stream().filter(navVO -> navVO.getParentId() == TOP_PARENT_ID).collect(Collectors.toList());
    }

    private List<NavVO> getAllNoParentTree(List<NavVO> list) {
        // 检查输入列表是否为空，若为空则直接返回空列表
        if (StringUtils.isEmpty(list)) {
            return Collections.emptyList();
        }

        // 遍历列表，将每个Nav实体复制到NavVO中，并存入映射表
        Map<Integer, List<NavVO>> map = list.stream().collect(Collectors.groupingBy(Nav::getParentId));

        list.forEach(navVO -> {
            List<NavVO> subNavList = map.get(navVO.getId());
            if (StringUtils.isNotEmpty(subNavList)) {
                navVO.setSubNavList(subNavList.stream().peek(subNav -> subNav.setPath(navVO.getPath() + "/" + subNav.getPath())).collect(Collectors.toList()));
            }
        });

        // 筛选出没有父级的导航项
        return list.stream().filter(navVO -> list.stream().noneMatch(nav -> nav.getId().equals(navVO.getParentId()))).collect(Collectors.toList());
    }

    private List<NavVO> getTreeByParentId(List<NavVO> list,Integer parentId) {
        // 检查输入列表是否为空，若为空则直接返回空列表
        if (StringUtils.isEmpty(list) || parentId == null || parentId == 0) {
            return Collections.emptyList();
        }

        // 遍历列表，将每个Nav实体复制到NavVO中，并存入映射表
        Map<Integer, List<NavVO>> map = list.stream().collect(Collectors.groupingBy(Nav::getParentId));

        list.forEach(navVO -> {
            List<NavVO> subNavList = map.get(navVO.getId());
            if (StringUtils.isNotEmpty(subNavList)) {
                navVO.setSubNavList(subNavList.stream().peek(subNav -> subNav.setPath(navVO.getPath() + "/" + subNav.getPath())).collect(Collectors.toList()));
            }
        });

        // 筛选出没有父级的导航项
        return list.stream().filter(navVO -> list.stream().noneMatch(nav -> nav.getId().equals(parentId))).collect(Collectors.toList());
    }
}
